Skip to content

Fix: 유저 닉네임 조회 추가#25

Merged
stoneTiger0912 merged 2 commits intomainfrom
feat/add-user-grpc
Mar 3, 2026
Merged

Fix: 유저 닉네임 조회 추가#25
stoneTiger0912 merged 2 commits intomainfrom
feat/add-user-grpc

Conversation

@stoneTiger0912
Copy link
Member

@stoneTiger0912 stoneTiger0912 commented Mar 3, 2026

Summary by CodeRabbit

  • New Features

    • 그룹 가입 신청 목록에 신청자 닉네임이 표시됩니다.
  • Improvements

    • 다중 사용자 조회 방식이 개선되어 대량 신청 목록 조회 시 처리 성능과 응답 일관성이 향상되었습니다.
    • 내 가입 신청 목록의 표시 정보가 더 정확하게 개선되었습니다.

@stoneTiger0912 stoneTiger0912 self-assigned this Mar 3, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff721bb and 5757af6.

📒 Files selected for processing (1)
  • src/main/resources/application.yml

Walkthrough

gRPC로 사용자 정보를 일괄 조회해 가입 폼 목록에 닉네임을 주입하도록 기능이 추가되었습니다. JoinInfo.of 시그니처가 닉네임을 받도록 변경되고, JoinMyInfo 레코드와 사용자 gRPC proto/클라이언트 설정이 추가되었습니다. (요약 50단어 이내)

Changes

Cohort / File(s) Summary
gRPC 설정 및 Proto 정의
src/main/proto/user.proto, src/main/resources/application.yml, src/main/java/flipnote/group/global/config/GrpcClientConfig.java
UserQueryService proto 추가(GetUser/GetUsers), application.yml에 gRPC 사용자 주소 추가 및 관련 설정 변경, 새로운 userQueryChannel/userQueryServiceStub 빈 추가.
서비스 로직 변경
src/main/java/flipnote/group/application/service/ApplicationFormService.java
User gRPC 스텁 주입 및 findJoinFormList()에서 userIds 추출 후 GetUsersRequest로 일괄 조회, 응답을 Map으로 변환하여 결과 팩토리에 전달하도록 변경.
포트/결과 변경
src/main/java/flipnote/group/application/port/in/result/FindJoinFormListResult.java, src/main/java/flipnote/group/application/port/in/result/FindMyJoinListResult.java, src/main/java/flipnote/group/api/dto/response/FindMyJoinListResponseDto.java
FindJoinFormListResult.of(...)에 Map<Long, GetUserResponse> userMap 파라미터 추가. FindMyJoinListResult 및 DTO에서 JoinInfoJoinMyInfo 타입 전환.
도메인 모델 변경
src/main/java/flipnote/group/domain/model/join/JoinInfo.java, src/main/java/flipnote/group/domain/model/join/JoinMyInfo.java
JoinInfo.of(JoinEntity, String nickname)로 시그니처 변경(하드코딩 닉네임 제거). 신규 JoinMyInfo 레코드 추가(groupJoinId, joinIntro, status).
경미한 문서 변경
src/main/java/flipnote/group/adapter/in/web/JoinController.java
메서드 Javadoc에서 todo 주석 한 줄 제거.

Sequence Diagram

sequenceDiagram
    actor Client
    participant Controller as JoinController
    participant Service as ApplicationFormService
    participant gRPC as UserQueryService (gRPC)
    participant Result as FindJoinFormListResult

    Client->>Controller: findGroupJoinList()
    Controller->>Service: findJoinFormList()
    Service->>Service: extract user IDs from joins
    Service->>gRPC: GetUsers(GetUsersRequest{user_ids})
    gRPC-->>Service: GetUsersResponse{users}
    Service->>Service: build Map<userId, GetUserResponse>
    Service->>Result: of(joinList, userMap)
    Result-->>Service: FindJoinFormListResult
    Service-->>Controller: Result
    Controller-->>Client: Response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰
gRPC 들고 달려왔네, 당근 대신 닉네임 🎩
한 번에 묶어 묻고, 이름을 되돌려줘요
JoinInfo는 이제 친구를 불러와
JoinMyInfo는 내 이야기만 속삭이네
후다닥, 번개같이 응답 왔당! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 changeset의 주요 변경사항을 명확하게 요약합니다. 유저 닉네임 조회 기능 추가라는 핵심 변경사항을 정확하게 반영하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-user-grpc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/main/java/flipnote/group/application/port/in/result/FindJoinFormListResult.java`:
- Around line 17-18: The current code calls
userMap.get(join.getUserId()).getNickname() which throws NPE when the user is
missing; update the logic around where JoinInfo.of(join, user.getNickname()) is
returned to handle a null GetUserResponse from userMap (e.g., retrieve
GetUserResponse user = userMap.get(join.getUserId()); then if user == null
either supply a null-safe fallback nickname like "Unknown User"/empty string or
throw an explicit, descriptive exception), and pass that safe value into
JoinInfo.of; adjust any callers or tests if they expect an exception vs
fallback.

In
`@src/main/java/flipnote/group/application/service/ApplicationFormService.java`:
- Around line 107-112: The gRPC call in ApplicationFormService uses
userQueryServiceStub.getUsers with GetUsersRequest without any deadline, risking
an indefinitely blocking thread; change the call site to apply a deadline (e.g.,
call userQueryServiceStub.withDeadlineAfter(...) or use Context/Deadline
utilities before invoking getUsers) so the remote call times out, and wrap the
invocation in a try/catch that catches io.grpc.StatusRuntimeException and maps
it to a suitable domain exception (e.g., UserServiceUnavailableException or a
specific ApplicationFormServiceException) to preserve error semantics; ensure
you reference the existing GetUsersRequest, userQueryServiceStub, and getUsers
symbols when making the change.

In `@src/main/proto/user.proto`:
- Around line 18-23: The GetUserResponse message currently exposes unnecessary
PII (email); update the proto to tighten the response for nickname mapping by
removing the email and profile_image_url fields and keeping only id and nickname
in GetUserResponse, or alternatively create a new lightweight RPC/message (e.g.,
GetUserNicknameResponse) that contains just int64 id and string nickname for the
mapping use-case; update any references to GetUserResponse in server handlers
and clients to use the new/trimmed message to avoid leaking email across
services.
- Line 7: The proto package declaration "package user_query;" in user.proto
doesn't match its repository location and triggers PACKAGE_DIRECTORY_MATCH
linting; fix by either moving the user.proto file into a directory that
corresponds to the package namespace (so its filesystem path matches package
user_query) or by changing the package declaration in user.proto from
"user_query" to the correct package name that matches the file's current
directory; ensure the package token exactly matches the target directory name
and re-run the proto linter.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 388a723 and ff721bb.

📒 Files selected for processing (10)
  • src/main/java/flipnote/group/adapter/in/web/JoinController.java
  • src/main/java/flipnote/group/api/dto/response/FindMyJoinListResponseDto.java
  • src/main/java/flipnote/group/application/port/in/result/FindJoinFormListResult.java
  • src/main/java/flipnote/group/application/port/in/result/FindMyJoinListResult.java
  • src/main/java/flipnote/group/application/service/ApplicationFormService.java
  • src/main/java/flipnote/group/domain/model/join/JoinInfo.java
  • src/main/java/flipnote/group/domain/model/join/JoinMyInfo.java
  • src/main/java/flipnote/group/global/config/GrpcClientConfig.java
  • src/main/proto/user.proto
  • src/main/resources/application.yml
💤 Files with no reviewable changes (1)
  • src/main/java/flipnote/group/adapter/in/web/JoinController.java

option java_outer_classname = "UserQueryProto";
option java_multiple_files = true;

package user_query;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, check if proto directory exists and list files
echo "=== Proto files structure ==="
if [ -d "src/main/proto" ]; then
    find src/main/proto -type f -name "*.proto" | head -20
else
    echo "Directory src/main/proto not found"
fi

echo ""
echo "=== Running package-directory mismatch check ==="
python3 <<'PY'
from pathlib import Path

root = Path("src/main/proto")
if not root.exists():
    print(f"Root path {root} does not exist")
else:
    violations = []
    for p in sorted(root.rglob("*.proto")):
        pkg = None
        try:
            content = p.read_text(encoding="utf-8")
            for line in content.splitlines():
                s = line.strip()
                if s.startswith("package ") and s.endswith(";"):
                    pkg = s[len("package "):-1].strip()
                    break
        except Exception as e:
            print(f"Error reading {p}: {e}")
            continue
        
        if not pkg:
            print(f"No package found in {p}")
            continue
        
        expected_dir = root / pkg.replace(".", "/")
        if p.parent != expected_dir:
            violations.append({
                'file': str(p),
                'package': pkg,
                'expected_dir': str(expected_dir),
                'actual_dir': str(p.parent)
            })
    
    if violations:
        print(f"Found {len(violations)} PACKAGE_DIRECTORY_MATCH violation(s):")
        for v in violations:
            print(f"  - File: {v['file']}")
            print(f"    Package: {v['package']}")
            print(f"    Expected dir: {v['expected_dir']}")
            print(f"    Actual dir: {v['actual_dir']}")
    else:
        print("No PACKAGE_DIRECTORY_MATCH violations found")
PY

Repository: FlipNoteTeam/FlipNote-Group

Length of output: 675


🏁 Script executed:

cat src/main/proto/user.proto

Repository: FlipNoteTeam/FlipNote-Group

Length of output: 682


package 선언과 파일 경로가 맞지 않아 proto lint가 실패합니다.

package user_query;면 Buf 규칙상 파일은 src/main/proto/user_query/ 디렉토리 하위에 있어야 합니다. 현재 위치(src/main/proto/user.proto)는 PACKAGE_DIRECTORY_MATCH 오류를 유발합니다. 파일을 src/main/proto/user_query/user.proto로 이동하거나 패키지 선언을 수정하세요.

🧰 Tools
🪛 Buf (1.65.0)

[error] 7-7: Files with package "user_query" must be within a directory "user_query" relative to root but were in directory "src/main/proto".

(PACKAGE_DIRECTORY_MATCH)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/proto/user.proto` at line 7, The proto package declaration "package
user_query;" in user.proto doesn't match its repository location and triggers
PACKAGE_DIRECTORY_MATCH linting; fix by either moving the user.proto file into a
directory that corresponds to the package namespace (so its filesystem path
matches package user_query) or by changing the package declaration in user.proto
from "user_query" to the correct package name that matches the file's current
directory; ensure the package token exactly matches the target directory name
and re-run the proto linter.

Comment on lines +18 to +23
message GetUserResponse {
int64 id = 1;
string email = 2;
string nickname = 3;
string profile_image_url = 4;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

현재 사용 목적 대비 응답 스키마가 과도하게 넓습니다.

닉네임 매핑 용도인데 email까지 함께 전달되어 서비스 간 PII 노출면이 커집니다. id, nickname 중심의 축소 응답(또는 별도 RPC)으로 분리하는 편이 안전합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/proto/user.proto` around lines 18 - 23, The GetUserResponse message
currently exposes unnecessary PII (email); update the proto to tighten the
response for nickname mapping by removing the email and profile_image_url fields
and keeping only id and nickname in GetUserResponse, or alternatively create a
new lightweight RPC/message (e.g., GetUserNicknameResponse) that contains just
int64 id and string nickname for the mapping use-case; update any references to
GetUserResponse in server handlers and clients to use the new/trimmed message to
avoid leaking email across services.

@stoneTiger0912 stoneTiger0912 merged commit e573ab7 into main Mar 3, 2026
1 check was pending
@stoneTiger0912 stoneTiger0912 deleted the feat/add-user-grpc branch March 3, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant